package com.aaa.springboot_rbac.service.impl;

import com.aaa.springboot_rbac.dao.MenuDao;
import com.aaa.springboot_rbac.service.MenuService;
import com.aaa.springboot_rbac.vo.TreeNode;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @FileName: MenuServiceImpl
 * @Description:
 * @Author: 张钰哲
 * @CreateTime: 2025/8/29 16:06
 * @Version: 1.0.0
 */
@Service
public class MenuServiceImpl implements MenuService {
    @Resource
    private MenuDao menuDao;
    @Override
    public List<TreeNode> queryTreeMenu() {
        List<TreeNode> treeNodeList = menuDao.queryAllMenu();
        //定义返回集合（树形数据）该集合是 以 树形结构  的数据形式 返回给前端
        List<TreeNode> treeNodeListResult = new ArrayList<>();
        // 判断 调用dao层接口获取的 所有的菜单数据是否为空
        // 两种判断方式 其一是自己写的。
/*        if (treeNodeList != null && treeNodeList.size() > 0) {

        }*/
        // 其二使用集合自带的判断是否为空的方式
        if (!CollectionUtils.isEmpty(treeNodeList)) { //不为空
            // 循环遍历集合的每一项，每一项都是一个 TreeNode 对象
            for (TreeNode treeNode : treeNodeList) {
                // 寻找一级菜单，即 TreeNode 对象的 parentId 实体属性 等于 0
                if (treeNode.getParentId()==0){ // 若等于0  该对象就是一级菜单
                    // 把该 一级菜单 的 对象 添加到要返回的 treeNodeListResult 集合中
                    treeNodeListResult.add(treeNode);
                    // 寻找 该 一级菜单的子菜单
                    //  调用查找并绑定孩子方法
                    bindChildren(treeNode,treeNodeList);
                }


            }
        }
        return treeNodeListResult;

    }

    @Override
    public List<TreeNode> queryTreeMenuByUserId(Integer userId) {
        List<TreeNode> treeNodeList = menuDao.queryMenuByUserId(userId);
        //定义返回集合（树形数据）该集合是 以 树形结构  的数据形式 返回给前端
        List<TreeNode> treeNodeListResult = new ArrayList<>();
        // 判断 调用dao层接口获取的 所有的菜单数据是否为空
        // 两种判断方式 其一是自己写的。
/*        if (treeNodeList != null && treeNodeList.size() > 0) {

        }*/
        // 其二使用集合自带的判断是否为空的方式
        if (!CollectionUtils.isEmpty(treeNodeList)) { //不为空
            // 循环遍历集合的每一项，每一项都是一个 TreeNode 对象
            for (TreeNode treeNode : treeNodeList) {
                // 寻找一级菜单，即 TreeNode 对象的 parentId 实体属性 等于 0
                if (treeNode.getParentId()==0){ // 若等于0  该对象就是一级菜单
                    // 把该 一级菜单 的 对象 添加到要返回的 treeNodeListResult 集合中
                    treeNodeListResult.add(treeNode);
                    // 寻找 该 一级菜单的子菜单
                    //  调用查找并绑定孩子方法
                    bindChildren(treeNode,treeNodeList);
                }


            }
        }
        return treeNodeListResult;

    }

    /**
     * 查询当前菜单节点的子菜单。
     * @param currentTreeNode 当前菜单节点
     * @param treeNodeList 所有菜单节点
     */
    private void bindChildren(TreeNode currentTreeNode, List<TreeNode> treeNodeList){
        // 循环遍历所有菜单节点
        for (TreeNode treeNode : treeNodeList){
            // 判断 当前 菜单节点的id 是否和 查询的所有菜单 parentId 相等
            // 若相等，即代表 当前菜单节点 是 父节点
            if (currentTreeNode.getId().equals(treeNode.getParentId())){
                //获取当前节点孩子集合
                List<TreeNode> children = currentTreeNode.getChildren();
                //判断孩子是否为null
                if(children==null){
                    //如果当前是找到的第一个孩子，肯定是null
                    // 因为第一次调用这个函数时，传入的是一级菜单的节点，
                    // 此时我们正在寻找一级菜单的子菜单，
                    // 此时我们并没有设置 孩子 集合，
                    // 所以我们要先 初始化一个孩子集合。
                    children = new ArrayList<>();
                }
                /*添加当前循环节点*/
                // 把寻找到的孩子节点，都放在 孩子 集合当中。
                children.add(treeNode);
                /*给当前节点设置孩子集合*/
                // 把孩子集合给父节点，即一级菜单。此时一级菜单就拥有了孩子集合了。
                // 之后 如果判断出 有一个对象  属于该菜单的子菜单，就不用再初始化了，直接添加到 孩子集合当中
                currentTreeNode.setChildren(children);
                //自己调用自己为当前循环节点再找孩子   递归
                bindChildren(treeNode,treeNodeList);
            }
        }
    }
}
